package com.sanyue.codingsettlement.job;

import com.sanyue.codingsettlement.model.entity.User;
import com.sanyue.codingsettlement.model.vo.PostVO;
import com.sanyue.codingsettlement.service.PostService;
import com.sanyue.codingsettlement.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author: Guan
 **/
// @Component
@Slf4j
public class PreCacheRecPost {

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private PostService postService;

    @Resource
    private UserService userService;


    @Resource
    private RedissonClient redissonClient;

    public static final String POST_RECOMMEND_KEY = "post:recommend:userId:";


    public static final String PRECACHE_JOB_LOCK = "post:precache:job:lock";


    @Scheduled(cron = "* */30 * * * *")
    public void doCacheRecPost() {

        //获取锁对象
        RLock lock = redissonClient.getLock(PRECACHE_JOB_LOCK);
        try {
            //尝试获取锁
            boolean res = lock.tryLock(0, -1L, TimeUnit.SECONDS);
            //获取锁成功
            if (res) {
                //指定定时任务
                System.out.println("定时任务开启了");
                //依次将每个用户对应的帖子数据保存到redis中
                for (User user : userService.list()) {
                    String key = POST_RECOMMEND_KEY + user.getId();
                    // 获取每个用户对应的帖子数据
                    List<PostVO> recommendPost = postService.getRecommendPostToJob(user);
                    try {
                        redisTemplate.opsForValue().set(key, recommendPost);
                    } catch (Exception e) {
                        log.error("redis set key error", e);
                    }
                }
                System.out.println("缓存成功");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }

    }

}
